home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / comm / term / term41source.lha / Extras / Source / term-Source.lha / termClip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-31  |  10.2 KB  |  622 lines

  1. /*
  2. **    termClip.c
  3. **
  4. **    Clipboard support routines
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12. STATIC struct IFFHandle    *ClipHandle;
  13. STATIC STRPTR         ClipBuffer,
  14.              ClipIndex;
  15. STATIC LONG         ClipSize,
  16.              ClipLength;
  17.  
  18.     /* CloseClip():
  19.      *
  20.      *    Close clipboard handle, stop reading.
  21.      */
  22.  
  23. VOID
  24. CloseClip()
  25. {
  26.     if(ClipHandle)
  27.     {
  28.         CloseIFF(ClipHandle);
  29.  
  30.         if(ClipHandle -> iff_Stream)
  31.             CloseClipboard((struct ClipboardHandle *)ClipHandle -> iff_Stream);
  32.  
  33.         FreeIFF(ClipHandle);
  34.  
  35.         ClipHandle = NULL;
  36.     }
  37.  
  38.     if(ClipBuffer)
  39.     {
  40.         FreeVecPooled(ClipBuffer);
  41.  
  42.         ClipBuffer = NULL;
  43.     }
  44. }
  45.  
  46.     /* GetClip(STRPTR Buffer,WORD Len,BYTE Filter):
  47.      *
  48.      *    Read text data from clipboard and put it into the supplied buffer.
  49.      */
  50.  
  51. WORD __regargs
  52. GetClip(STRPTR Buffer,WORD Len,BYTE Filter)
  53. {
  54.     WORD BytesPut = 0;
  55.  
  56.         /* Is the read buffer already exhausted? */
  57.  
  58.     if(!ClipLength)
  59.     {
  60.             /* Is there still any data to read? */
  61.  
  62.         if(ClipSize)
  63.         {
  64.             WORD Size = MIN(ClipSize,1024);
  65.  
  66.                 /* Try to read the data and return failure if necessary. */
  67.  
  68.             if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
  69.                 return(-1);
  70.             else
  71.             {
  72.                 ClipSize    -= Size;
  73.                 ClipLength     = Size;
  74.                 ClipIndex     = ClipBuffer;
  75.             }
  76.         }
  77.         else
  78.         {
  79.                 /* We just parsed a single chunk, now go on and
  80.                  * look for another one.
  81.                  */
  82.  
  83.             if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  84.             {
  85.                 struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
  86.  
  87.                 if(ContextNode -> cn_Type == ID_FTXT)
  88.                 {
  89.                     WORD Size;
  90.  
  91.                     ClipSize    = ContextNode -> cn_Size;
  92.                     Size        = MIN(ClipSize,1024);
  93.  
  94.                     if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
  95.                         return(-1);
  96.                     else
  97.                     {
  98.                         ClipSize    -= Size;
  99.                         ClipLength     = Size;
  100.                         ClipIndex     = ClipBuffer;
  101.                     }
  102.                 }
  103.                 else
  104.                     return(-1);
  105.             }
  106.             else
  107.                 return(-1);
  108.         }
  109.     }
  110.  
  111.         /* The following loop processes the contents of
  112.          * the clipboard buffer read. Special characters
  113.          * such as LF and CR will be converted according
  114.          * to the current settings if enabled. No bytes
  115.          * will be lost, though.
  116.          */
  117.  
  118.     while(ClipLength && BytesPut < Len)
  119.     {
  120.         if(*ClipIndex == '\n')
  121.         {
  122.             if(Filter)
  123.             {
  124.                 *Buffer++ = *ClipIndex++;
  125.  
  126.                 BytesPut++;
  127.  
  128.                 ClipLength--;
  129.             }
  130.             else
  131.             {
  132.                 switch(Config -> TerminalConfig -> SendLF)
  133.                 {
  134.                     case EOL_IGNORE:
  135.  
  136.                         ClipIndex++;
  137.                         ClipLength--;
  138.  
  139.                         break;
  140.  
  141.                     case EOL_LFCR:
  142.  
  143.                         if(BytesPut + 2 <= Len)
  144.                         {
  145.                             *Buffer++ = '\n';
  146.                             *Buffer++ = '\r';
  147.  
  148.                             BytesPut += 2;
  149.  
  150.                             ClipLength--;
  151.                             ClipIndex++;
  152.                         }
  153.                         else
  154.                             return(BytesPut);
  155.  
  156.                         break;
  157.  
  158.                     case EOL_CRLF:
  159.  
  160.                         if(BytesPut + 2 <= Len)
  161.                         {
  162.                             *Buffer++ = '\r';
  163.                             *Buffer++ = '\n';
  164.  
  165.                             BytesPut += 2;
  166.  
  167.                             ClipLength--;
  168.                             ClipIndex++;
  169.                         }
  170.                         else
  171.                             return(BytesPut);
  172.  
  173.                         break;
  174.  
  175.                     case EOL_LF:
  176.  
  177.                         *Buffer++ = *ClipIndex++;
  178.  
  179.                         BytesPut++;
  180.  
  181.                         ClipLength--;
  182.  
  183.                         break;
  184.  
  185.                     case EOL_CR:
  186.  
  187.                         *Buffer++ = '\r';
  188.  
  189.                         BytesPut++;
  190.  
  191.                         ClipIndex++;
  192.                         ClipLength--;
  193.  
  194.                         break;
  195.                 }
  196.             }
  197.         }
  198.         else
  199.         {
  200.             if(*ClipIndex == '\r')
  201.             {
  202.                 if(Filter)
  203.                 {
  204.                     ClipIndex++;
  205.                     ClipLength--;
  206.                 }
  207.                 else
  208.                 {
  209.                     switch(Config -> TerminalConfig -> SendCR)
  210.                     {
  211.                         case EOL_IGNORE:
  212.  
  213.                             ClipIndex++;
  214.                             ClipLength--;
  215.  
  216.                             break;
  217.  
  218.                         case EOL_CRLF:
  219.  
  220.                             if(BytesPut + 2 <= Len)
  221.                             {
  222.                                 *Buffer++ = '\r';
  223.                                 *Buffer++ = '\n';
  224.  
  225.                                 BytesPut += 2;
  226.  
  227.                                 ClipLength--;
  228.                                 ClipIndex++;
  229.                             }
  230.                             else
  231.                                 return(BytesPut);
  232.  
  233.                             break;
  234.  
  235.                         case EOL_LFCR:
  236.  
  237.                             if(BytesPut + 2 <= Len)
  238.                             {
  239.                                 *Buffer++ = '\n';
  240.                                 *Buffer++ = '\r';
  241.  
  242.                                 BytesPut += 2;
  243.  
  244.                                 ClipLength--;
  245.                                 ClipIndex++;
  246.                             }
  247.                             else
  248.                                 return(BytesPut);
  249.  
  250.                             break;
  251.  
  252.                         case EOL_CR:
  253.  
  254.                             *Buffer++ = *ClipIndex++;
  255.  
  256.                             BytesPut++;
  257.  
  258.                             ClipLength--;
  259.  
  260.                             break;
  261.  
  262.                         case EOL_LF:
  263.  
  264.                             *Buffer++ = '\n';
  265.  
  266.                             BytesPut++;
  267.  
  268.                             ClipIndex++;
  269.                             ClipLength--;
  270.  
  271.                             break;
  272.                     }
  273.                 }
  274.             }
  275.             else
  276.             {
  277.                 register UBYTE c = *ClipIndex++;
  278.  
  279.                 ClipLength--;
  280.  
  281.                 if(!Filter || IsPrintable[c])
  282.                 {
  283.                     *Buffer++ = c;
  284.  
  285.                     BytesPut++;
  286.                 }
  287.             }
  288.         }
  289.     }
  290.  
  291.     return(BytesPut);
  292. }
  293.  
  294.     /* OpenClip():
  295.      *
  296.      *    Open the clipboard for sequential reading.
  297.      */
  298.  
  299. BYTE __regargs
  300. OpenClip(LONG Unit)
  301. {
  302.     BYTE Error;
  303.  
  304.     CloseClip();
  305.  
  306.     if(ClipBuffer = (STRPTR)AllocVecPooled(1024,MEMF_ANY))
  307.     {
  308.         if(ClipHandle = AllocIFF())
  309.         {
  310.             if(ClipHandle -> iff_Stream = (ULONG)OpenClipboard(Unit))
  311.             {
  312.                 InitIFFasClip(ClipHandle);
  313.  
  314.                 if(!OpenIFF(ClipHandle,IFFF_READ))
  315.                 {
  316.                     if(!StopChunk(ClipHandle,ID_FTXT,ID_CHRS))
  317.                     {
  318.                         if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  319.                         {
  320.                             struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
  321.  
  322.                             if(ContextNode -> cn_Type == ID_FTXT)
  323.                             {
  324.                                 ClipSize    = ContextNode -> cn_Size;
  325.                                 ClipLength    = 0;
  326.  
  327.                                 return(CLIPERR_NONE);
  328.                             }
  329.                             else
  330.                                 Error = CLIPERR_NOTEXT;
  331.                         }
  332.                         else
  333.                             Error = CLIPERR_NOTEXT;
  334.                     }
  335.                     else
  336.                         Error = CLIPERR_IFF;
  337.                 }
  338.                 else
  339.                     Error = CLIPERR_OPEN;
  340.             }
  341.             else
  342.                 Error = CLIPERR_OPEN;
  343.         }
  344.         else
  345.             Error = CLIPERR_MEM;
  346.     }
  347.     else
  348.         Error = CLIPERR_MEM;
  349.  
  350.     CloseClip();
  351.  
  352.     return(Error);
  353. }
  354.  
  355.     /* GetClipContents(LONG Unit,APTR *Buffer,LONG *Size):
  356.      *
  357.      *    Merge text contents of the clipboard into a single string.
  358.      */
  359.  
  360. BYTE __regargs
  361. GetClipContents(LONG Unit,APTR *Buffer,LONG *Size)
  362. {
  363.     struct IFFHandle    *Handle;
  364.     LONG             Bytes = 0;
  365.     APTR             Store = NULL;
  366.  
  367.     if(Handle = AllocIFF())
  368.     {
  369.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Unit))
  370.         {
  371.             InitIFFasClip(Handle);
  372.  
  373.             if(!OpenIFF(Handle,IFFF_READ))
  374.             {
  375.                 if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  376.                 {
  377.                     struct ContextNode *Node;
  378.  
  379.                     while(!ParseIFF(Handle,IFFPARSE_SCAN))
  380.                     {
  381.                         Node = CurrentChunk(Handle);
  382.  
  383.                         if(Node -> cn_Type == ID_FTXT)
  384.                             Bytes += Node -> cn_Size;
  385.                     }
  386.                 }
  387.  
  388.                 CloseIFF(Handle);
  389.             }
  390.  
  391.             if(Bytes)
  392.             {
  393.                 if(!OpenIFF(Handle,IFFF_READ))
  394.                 {
  395.                     if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  396.                     {
  397.                         if(Store = AllocVecPooled(Bytes,MEMF_ANY))
  398.                         {
  399.                             STRPTR             Index        = Store;
  400.                             LONG             BytesRead    = 0;
  401.                             struct ContextNode    *Node;
  402.  
  403.                             while(!ParseIFF(Handle,IFFPARSE_SCAN) && BytesRead < Bytes)
  404.                             {
  405.                                 Node = CurrentChunk(Handle);
  406.  
  407.                                 if(Node -> cn_Type == ID_FTXT)
  408.                                 {
  409.                                     LONG Count = Node -> cn_Size;
  410.  
  411.                                     if(BytesRead + Count > Bytes)
  412.                                         Count = Bytes - BytesRead;
  413.  
  414.                                     if(Count > 0)
  415.                                     {
  416.                                         if((Count = ReadChunkBytes(Handle,Index,Count)) > 0)
  417.                                         {
  418.                                             Index        += Count;
  419.                                             BytesRead    += Count;
  420.                                         }
  421.                                     }
  422.                                 }
  423.                             }
  424.  
  425.                             Bytes = BytesRead;
  426.                         }
  427.                     }
  428.  
  429.                     CloseIFF(Handle);
  430.                 }
  431.             }
  432.  
  433.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  434.         }
  435.  
  436.         FreeIFF(Handle);
  437.     }
  438.  
  439.     if(Store && !Bytes)
  440.     {
  441.         FreeVecPooled(Store);
  442.  
  443.         Store = NULL;
  444.     }
  445.  
  446.     *Buffer    = Store;
  447.     *Size    = Bytes;
  448.  
  449.     return((BYTE)(Store != NULL));
  450. }
  451.  
  452.     /* AddClip(STRPTR Buffer,LONG Size):
  453.      *
  454.      *    Merge previous clipboard contents with new text,
  455.      *    then store the new string in the clipboard.
  456.      */
  457.  
  458. BYTE __regargs
  459. AddClip(STRPTR Buffer,LONG Size)
  460. {
  461.     LONG    Bytes;
  462.     APTR    Store;
  463.  
  464.     if(GetClipContents(Config -> ClipConfig -> ClipboardUnit,&Store,&Bytes))
  465.     {
  466.         struct IFFHandle    *Handle;
  467.         BYTE             Success = FALSE;
  468.  
  469.         if(Handle = AllocIFF())
  470.         {
  471.             if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  472.             {
  473.                 InitIFFasClip(Handle);
  474.  
  475.                 if(!OpenIFF(Handle,IFFF_WRITE))
  476.                 {
  477.                     if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  478.                     {
  479.                         if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  480.                         {
  481.                             if(WriteChunkBytes(Handle,Store,Bytes) == Bytes)
  482.                             {
  483.                                 if(WriteChunkBytes(Handle,Buffer,Size) == Size)
  484.                                 {
  485.                                     if(!PopChunk(Handle))
  486.                                         Success = TRUE;
  487.                                 }
  488.                             }
  489.                         }
  490.                     }
  491.  
  492.                     if(Success)
  493.                     {
  494.                         if(PopChunk(Handle))
  495.                             Success = FALSE;
  496.                     }
  497.  
  498.                     CloseIFF(Handle);
  499.                 }
  500.  
  501.                 CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  502.             }
  503.  
  504.             FreeIFF(Handle);
  505.         }
  506.  
  507.         FreeVecPooled(Store);
  508.  
  509.         return(Success);
  510.     }
  511.     else
  512.         return(SaveClip(Buffer,Size));
  513. }
  514.  
  515.     /* SaveClip(STRPTR Buffer,LONG Size):
  516.      *
  517.      *    Send a given text buffer to the clipboard.
  518.      */
  519.  
  520. BYTE __regargs
  521. SaveClip(STRPTR Buffer,LONG Size)
  522. {
  523.     BYTE Success = FALSE;
  524.  
  525.     if(Size > 0)
  526.     {
  527.         struct IFFHandle *Handle;
  528.  
  529.         if(Handle = AllocIFF())
  530.         {
  531.             if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  532.             {
  533.                 InitIFFasClip(Handle);
  534.  
  535.                 if(!OpenIFF(Handle,IFFF_WRITE))
  536.                 {
  537.                     if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  538.                     {
  539.                         if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  540.                         {
  541.                             if(WriteChunkBytes(Handle,Buffer,Size) == Size)
  542.                             {
  543.                                 if(!PopChunk(Handle))
  544.                                     Success = TRUE;
  545.                             }
  546.                         }
  547.                     }
  548.  
  549.                     if(Success)
  550.                     {
  551.                         if(PopChunk(Handle))
  552.                             Success = FALSE;
  553.                     }
  554.  
  555.                     CloseIFF(Handle);
  556.                 }
  557.  
  558.                 CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  559.             }
  560.  
  561.             FreeIFF(Handle);
  562.         }
  563.     }
  564.  
  565.     return(Success);
  566. }
  567.  
  568.     /* LoadClip(STRPTR Buffer,LONG Size):
  569.      *
  570.      *    Put the contents of the clipboard into a given
  571.      *    buffer. Note that only the first FTXT chunk will
  572.      *    be read. Since this code will only be called by
  573.      *    the clipboard server process which serves the
  574.      *    string gadget editing hook, this will hopefully
  575.      *    not be fatal. If you want more data to be read,
  576.      *    including multiple FTXT chunks, use the OpenClip(),
  577.      *    GetClip(), CloseClip() combo above.
  578.      */
  579.  
  580. LONG __regargs
  581. LoadClip(STRPTR Buffer,LONG Size)
  582. {
  583.     struct IFFHandle    *Handle;
  584.     LONG             Bytes = 0;
  585.  
  586.     if(Handle = AllocIFF())
  587.     {
  588.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  589.         {
  590.             InitIFFasClip(Handle);
  591.  
  592.             if(!OpenIFF(Handle,IFFF_READ))
  593.             {
  594.                 if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  595.                 {
  596.                     if(!ParseIFF(Handle,IFFPARSE_SCAN))
  597.                     {
  598.                         struct ContextNode *ContextNode = CurrentChunk(Handle);
  599.  
  600.                         if(ContextNode -> cn_Type == ID_FTXT)
  601.                         {
  602.                             if(Size > ContextNode -> cn_Size)
  603.                                 Size = ContextNode -> cn_Size;
  604.  
  605.                             if(ReadChunkRecords(Handle,Buffer,Size,1))
  606.                                 Bytes = Size;
  607.                         }
  608.                     }
  609.                 }
  610.  
  611.                 CloseIFF(Handle);
  612.             }
  613.  
  614.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  615.         }
  616.  
  617.         FreeIFF(Handle);
  618.     }
  619.  
  620.     return(Bytes);
  621. }
  622.